//
//  CSMapSearchListView.swift
//  Cycling
//
//  Created by CSS on 3/31/23.
//

import UIKit

import MapboxSearch

class CSMapSearchListView: UIView {
    
    lazy private var navContentView: UIView = {
        let navContentView: UIView = .forAutoLayout()
        navContentView.heightAnchor.constraint(equalToConstant: 44).isActive = true
        navContentView.addSegmentLine()
        return navContentView
    }()
    lazy private var searchField: UITextField = {
        let searchField: UITextField = .forAutoLayout()
        searchField.delegate = self
        searchField.addTarget(self, action: #selector(searchTextValueChanged(_:)), for: .editingChanged)
        searchField.returnKeyType = .search
        searchField.layer.borderColor = UIColor.color(withHexString: "#EEEEEE").cgColor
        searchField.layer.borderWidth = 1
        searchField.layer.cornerRadius = 4
        searchField.text = "二七纪念塔"
        
        searchField.clearButtonMode = .whileEditing
        
        let searchIconView = UIImageView(image: .init(named: "sousuo"))
        searchIconView.translatesAutoresizingMaskIntoConstraints = false
        let searchIconContentView = UIView()
        searchIconContentView.backgroundColor = .clear
        searchIconContentView.frame = .init(x: 0, y: 0, width: searchIconView.intrinsicContentSize.width + 16, height: 30)
        searchIconContentView.addSubview(searchIconView)
        
        NSLayoutConstraint.activate([
            searchIconView.centerXAnchor.constraint(equalTo: searchIconContentView.centerXAnchor),
            searchIconView.centerYAnchor.constraint(equalTo: searchIconContentView.centerYAnchor),
            
            searchIconContentView.widthAnchor.constraint(equalToConstant: searchIconView.intrinsicContentSize.width + 16)
        ])
        
        searchField.leftView = searchIconContentView
        searchField.leftViewMode = .always
        
        return searchField
    }()
    lazy private var contentView: UIView = .forAutoLayout()
    lazy private var tableView: UITableView = {
        let tableView: UITableView = .init(frame: bounds, style: .plain)
        tableView.delegate = self
        tableView.dataSource = self
        tableView.separatorStyle = .none
        tableView.translatesAutoresizingMaskIntoConstraints = false
        
        let tableFooterView = UIView()
        tableFooterView.backgroundColor = .clear
        tableView.tableFooterView = tableFooterView
        
        return tableView
    }()
    lazy private var clearButton: UIButton = {
        let clearButton:UIButton = .init(type: .custom)
        clearButton.backgroundColor = .clear
        clearButton.translatesAutoresizingMaskIntoConstraints = false
        clearButton.addTarget(self, action: #selector(clearButtonAction(_:)), for: .touchUpInside)
        clearButton.setTitle("清空搜索列表", for: .normal)
        clearButton.setTitleColor(.color(withHexString: "#333333"), for: .normal)
        clearButton.titleLabel?.font = .systemFont(ofSize: 16)
        clearButton.heightAnchor.constraint(equalToConstant: 44).isActive = true
        clearButton.addSegmentLine(onBottom: false)
        return clearButton
    }()
    lazy private var dismissControl: UIControl = {
        let control: UIControl = .forAutoLayout()
        control.backgroundColor = .clear
        control.addTarget(self, action: #selector(dismissButtonAction(_:)), for: .touchUpInside)
        return control
    }()
    
    private var componentViews: [UIView] {
        [ dismissControl, navContentView, contentView ]
    }
    private var contentComponentViews: [UIView] {
        [tableView, clearButton]
    }
    
    private var resultModels: [CSSearchResultModel] = CSSearchResultModel.testDatas()
    private var searchResultsModel: [SearchResult] = []
    private var searchResultsShouldReset = false
    
    lazy private var searchEngine: SearchEngine = {
        let searchEngine = SearchEngine()
        searchEngine.delegate = self
        return searchEngine
    }()
    
    public var searchListViewBlock: ((SelectType, Any?) -> Void)?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setup()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    @discardableResult
    override func becomeFirstResponder() -> Bool {
        searchField.becomeFirstResponder()
        return false
    }
    
    private func setup() {
        
        backgroundColor = .black.withAlphaComponent(0)
        
        navContentView.backgroundColor = .white
        contentView.backgroundColor = .white
        
        addSubviews(componentViews)
        contentView.addSubviews(contentComponentViews)
        
        makeConstraints()
        
        tableViewSetup()
        searchContentSetup()
        
        if let searchText = searchField.text, searchText.count > 0 {
            requestSearchData(withKeyString: searchText)
        }
    }
    
    private func tableViewSetup() {
        tableView.registerDefaultNibCell(withClasss: [CSMapSearchListCell.self, CSMapSearchListResultCell.self])
        tableView.estimatedRowHeight = 44
    }
    
    private func searchContentSetup() {
        let backButton: UIButton = .init(type: .custom)
        backButton.translatesAutoresizingMaskIntoConstraints = false
        backButton.setImage(.init(named: "nav_back"), for: .normal)
        backButton.addTarget(self, action: #selector(dismissButtonAction(_:)), for: .touchUpInside)
        backButton.contentEdgeInsets = .init(top: 0, left: 18, bottom: 0, right: 10)
        backButton.setContentHuggingPriority(.required, for: .horizontal)
        backButton.setContentCompressionResistancePriority(.required, for: .horizontal)
        
        navContentView.addSubviews([backButton, searchField])
        
        let constraints = [
            backButton.leadingAnchor.constraint(equalTo: navContentView.leadingAnchor),
            backButton.topAnchor.constraint(equalTo: navContentView.topAnchor),
            backButton.bottomAnchor.constraint(equalTo: navContentView.bottomAnchor),
            
            searchField.leadingAnchor.constraint(equalTo: backButton.trailingAnchor),
            searchField.trailingAnchor.constraint(equalTo: navContentView.trailingAnchor, constant: -18),
            searchField.heightAnchor.constraint(equalToConstant: 30),
            searchField.centerYAnchor.constraint(equalTo: navContentView.centerYAnchor)
        ]
        NSLayoutConstraint.activate(constraints)
        
    }
    
    private func makeConstraints() {
        
        dismissControl.pinTo(parentView: self)
        
        let constraints = [
            
            navContentView.leadingAnchor.constraint(equalTo: leadingAnchor),
            navContentView.trailingAnchor.constraint(equalTo: trailingAnchor),
            navContentView.topAnchor.constraint(equalTo: topAnchor),
            
            contentView.leadingAnchor.constraint(equalTo: leadingAnchor),
            contentView.trailingAnchor.constraint(equalTo: trailingAnchor),
            contentView.topAnchor.constraint(equalTo: navContentView.bottomAnchor),
            contentView.heightAnchor.constraint(equalToConstant: 345),
            
            clearButton.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            clearButton.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
            clearButton.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
            
            tableView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            tableView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
            tableView.topAnchor.constraint(equalTo: contentView.topAnchor),
            tableView.bottomAnchor.constraint(equalTo: clearButton.topAnchor)
        ]
        
        NSLayoutConstraint.activate(constraints)
    }

}

// MARK: tableView处理类
extension CSMapSearchListView: UITableViewDataSource, UITableViewDelegate {
    
    func numberOfSections(in tableView: UITableView) -> Int {
        2
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 0 {
            return searchResultsModel.count
        }
        return resultModels.count + 1
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.section == 0 {
            let cell = CSMapSearchListResultCell.reuseCell(forTableView: tableView)
            if indexPath.row < searchResultsModel.count {
                cell.searchResult = searchResultsModel[indexPath.row]
            }
            return cell
        }
        let cell = CSMapSearchListCell.reuseCell(forTableView: tableView)
        
        if resultModels.count > indexPath.row {
            cell.model = resultModels[indexPath.row]
        } else {
            cell.valueShow(withType: 1)
        }
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        if section == 0 {
            return 0
        }
        return 35
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        if section == 0 {
            return UIView()
        }
        let headerView: UIView = .init()
        headerView.backgroundColor = .white
        
        let headerTitleLbl: UILabel = .forAutoLayout()
        headerTitleLbl.font = .systemFont(ofSize: 16)
        headerTitleLbl.textColor = .color(withHexString: "#333333")
        headerTitleLbl.text = "历史记录"
        
        headerView.addSubview(headerTitleLbl)
        
        let constraints = [
            headerTitleLbl.leadingAnchor.constraint(equalTo: headerView.leadingAnchor, constant: 23),
            headerTitleLbl.centerYAnchor.constraint(equalTo: headerView.centerYAnchor)
        ]
        NSLayoutConstraint.activate(constraints)
        
        headerView.addSegmentLine()
        
        return headerView
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.section == 0 {
            return UITableView.automaticDimension
        }
        return tableView.estimatedRowHeight
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if indexPath.section == 0 {
            if searchResultsModel.count > indexPath.row {
                searchListViewBlock?(.goToSelectRoute, searchResultsModel[indexPath.row].coordinate)
                dismissMapSelectView()
            }
        }
    }
    
}

// MARK: UITextField委托处理类
extension CSMapSearchListView: UITextFieldDelegate {
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
}

// MARK: 事件处理类
private extension CSMapSearchListView {
    
    @objc func clearButtonAction(_ sender: Any) {
        searchListViewBlock?(.clear, nil)
    }
    
    @objc func dismissButtonAction(_ sender: Any) {
        dismissMapSelectView()
    }
    
    @objc private func searchTextValueChanged(_ textField: UITextField) {
        requestSearchData(withKeyString: textField.text)
    }
    
}

// MARK: SearchEngine委托处理类
extension CSMapSearchListView: SearchEngineDelegate {
    
    func resultResolved(result: MapboxSearch.SearchResult, searchEngine: MapboxSearch.SearchEngine) {
        if searchResultsShouldReset {
            emptySearchModels()
        }
        searchResultsShouldReset = false
        searchResultsModel.append(result)
        DispatchQueue.main.async { [weak self] in
            self?.tableView.reloadData()
        }
    }
    
    func searchErrorHappened(searchError: MapboxSearch.SearchError, searchEngine: MapboxSearch.SearchEngine) {
        if searchResultsShouldReset {
            emptySearchModels()
        }
        searchResultsShouldReset = false
    }
    
    
    func suggestionsUpdated(suggestions: [SearchSuggestion], searchEngine: SearchEngine) {
        if suggestions.count == 0 {
            emptySearchModels()
            searchResultsShouldReset = false
            return
        }
        searchResultsShouldReset = true
        suggestions.forEach({
            searchEngine.select(suggestion: $0)
        })
    }
    
}

// MARK: UI处理类
private extension CSMapSearchListView {
    
    func dismissMapSelectView() {
        searchField.resignFirstResponder()
        isHidden = true
    }
    
}

// MARK: 数据处理类
private extension CSMapSearchListView {
    
    func requestSearchData(withKeyString keyString: String?) {
        guard let keyString = keyString, keyString.count > 0 else {
            emptySearchModels()
            return
        }
        searchEngine.search(query: keyString)
    }
    
    func emptySearchModels() {
        searchResultsModel.removeAll()
        DispatchQueue.main.async { [weak self] in
            self?.tableView.reloadData()
        }
    }
    
}

// MARK: 枚举类
extension CSMapSearchListView {
    
    enum SelectType: Int {
        case clear, more, goToSelectRoute
    }
    
}
